﻿//#define TEST
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using Configuration;
using PLC;
using PLC.Base;
using PLC.Manager;
using PumpAlgorithm;

namespace Business.Base
{
    public abstract class BaseService
    {
        #region 私有变量
        private ExperimentType experimentType;
        private PumpType pumpType;
        private int dn;
        private double transformationRatio;
        IDBManager experimentAttachInfoDBManager;
        IDBManager experimentRecordDBManager;





        //#if TEST
        // private IEnvDataManager envDataManager = new EnvDataManagerStub();
        //#else

        //数据采集管理器
        private IEnvDataManager envDataManager;

        //#endif   
        // 数据库管理
        //DBManager experimentDBManager = new DBManager(ExperimentRule.experimentTable,ExperimentRule.experimentDBMap);

        
        
        #endregion

        #region 属性

        /// <summary>
        /// 实验类型
        /// </summary>
        public ExperimentType ExperimentType
        {
            get => experimentType;
            set
            {
                experimentType = this.experimentType = value;
            }
        }
        
        /// <summary>
        /// 泵类型
        /// </summary>
        public PumpType PumpType { get => pumpType; set => pumpType = value; }

        /// <summary>
        /// DN地址
        /// </summary>
        public int Dn { get => dn; set => dn = value; }

        /// <summary>
        /// 变比
        /// </summary>
        public double TransformationRatio { get => transformationRatio; set => transformationRatio = value; }

        #endregion

        #region 待继承的属性

        /// <summary>
        /// canonicalAlgorithm 算法
        /// </summary>
        protected CanonicalAlgorithm canonicalAlgorithm = null;
        

        
        /// <summary>
        /// 实验基础数据的管理
        /// </summary>        
       // protected DBManager ExperimentDBManager => experimentDBManager;

        /// <summary>
        /// 实验附加数据管理，如数据信息根据泵类型不同，会有附加的字段
        /// </summary>
        protected IDBManager ExperimentAttachInfoDBManager { get=> experimentAttachInfoDBManager; }

        /// <summary>
        /// 实验记录数据管理。
        /// </summary>
        protected IDBManager ExperimentRecordDBManager { get=> experimentRecordDBManager; }


        /// <summary>
        /// 实验Excel结果
        /// </summary>
        protected abstract ExperimentExcelManager ExperimentExcelManager { get; }
        


        #endregion


        #region 算法封装

        /// <summary>
        /// 初始化算法对象
        /// </summary>
        /// <param name="experiment">传入试验数据</param>
        public abstract void initAlgorithm(Experiment experiment);

        /// <summary>
        /// 根据获取的数据，计算出一条记录数据
        /// </summary>
        /// <param name="data">硬件获取到的数据</param>
        /// <returns>试验中的记录数据</returns>
        public abstract ExperimentRecord CaculateDataFromRecord(EnvData data);

        /// <summary>
        /// 计算绘图的数据
        /// </summary>
        /// <param name="experiment">当前试验数据</param>
        /// <returns>绘图数据（包括绘图所需要的所有数据）</returns>
        public abstract BaseChartData CaculateChartData(Experiment experiment);

        /// <summary>
        /// 根据试验数据，试验的结论
        /// </summary>
        /// <param name="experiment"></param>
        public abstract void CaculateExperimentResult(ref Experiment experiment);



        #endregion

        #region 数据和计算读取

        private DBManager initDBManager(string tableName,Dictionary<string,string> dic)
        {
           
           
            DBManager dBManager = new DBManager(tableName, dic);
            return dBManager;
        }

        public void init(Experiment experiment)
        {
            this.experimentType = experiment.ExperimentType;
            this.pumpType = experiment.PumpType;
            this.dn = experiment.Dn;
            this.transformationRatio = experiment.TransFormRadio;
            this.envDataManager = EnvDataManagerSimpleFactory.createEnvDataManager(EnvDataConfig.EnvDataType, dn,transformationRatio)·

            this.initAlgorithm(experiment);
            this.initDBManager();
        }

        /// <summary>
        /// 初始化数据库操作组件
        /// </summary>
        public void initDBManager()
        {
            /*Boolean success = false;
            for (int i = 0; i < ExperimentRule.ExperimentRuleList.Count; i++)
            {
                ExperimentRule rule = ExperimentRule.ExperimentRuleList[i];
                if (rule.ExperimentType == ExperimentType.Npsh)
                {
                    success = true;
                    //experimentAttachInfoDBManager = initDBManager(rule.AttachInfoTable, rule.DbFiledMap);
                    experimentRecordDBManager = initDBManager(rule.RecordTable, rule.DbRecordFieldMap);
                    break;
                }
                else if (rule.PumpType == pumpType && rule.ExperimentType == experimentType)
                {
                    success = true;
                    experimentAttachInfoDBManager = initDBManager(rule.AttachInfoTable, rule.DbFiledMap);
                    experimentRecordDBManager = initDBManager(rule.RecordTable,rule.DbRecordFieldMap);
                    break;
                }
            }
            if (!success)
            {
                throw new Exception("不支持当前测试类型！");
            }*/
        }

        /// <summary>
        /// 打开连接，开始读取数据
        /// </summary>
        public void StartRead()
        {
            envDataManager.Open();
            //envDataManager.Connect();
        }

        /// <summary>
        /// 从硬件读取数据
        /// </summary>
        /// <param name="transformationRatio"></param>
        /// <returns></returns>
        public EnvData FetchDataFromEnv(int dn,double transformationRatio)
        {
            return envDataManager.ReadData();
            //return envDataManager.ReadData(dn,transformationRatio);
        }

        /// <summary>
        /// 关闭连接，结束数据读取
        /// </summary>
        public void EndRead()
        {
            envDataManager.Close();
        }



        #endregion

        #region 数据操作

        public void QueryExperimentAttachInfo(ref Experiment experiment)
        {
            
          

        }

        public DataTable QueryExperiment(string entity, BaseQuery query)
        {
            return DBManager.dbManagerDic[entity].GetDataList(query);
        }

        /// <summary>
        /// 获取符合条件的记录数量
        /// </summary>
        /// <param name="query">查询条件对象</param>
        /// <returns>查询结果</returns>
        public int GetCount(string entity,BaseQuery query)
        {
            return DBManager.dbManagerDic[entity].GetCount(query);
        }

        private string getAttachInfoDBManager(Experiment experiment)
        {
            if (experiment.ExperimentType == ExperimentType.Npsh)
            {
                return null;
            }
            if (experiment.ExperimentType == ExperimentType.Perf && experiment.PumpType == PumpType.CentrifugalPump)
            {
                return DBManager.ENTITY_CENTRIFUGALPUMPATTACHINFO;
            }
            if (experiment.ExperimentType == ExperimentType.Perf && experiment.PumpType == PumpType.ScrewPump)
            {
                return DBManager.ENTITY_SCREWPUMPATTACHINFO;
            }
            return null;
        }

        private string getRecordDBManager(Experiment experiment)
        {
            if (experiment.ExperimentType == ExperimentType.Perf && experiment.PumpType == PumpType.CentrifugalPump)
            {
                return DBManager.ENTITY_CENTRIFUGALPUMPRECORD;
            }
            if (experiment.ExperimentType == ExperimentType.Perf && experiment.PumpType == PumpType.ScrewPump)
            {
                return DBManager.ENTITY_SCREWPUMPRECORD;
            }
            if (experiment.ExperimentType == ExperimentType.Npsh)
            {
                return DBManager.ENTITY_NSPHRECORD;
            }
            return null;
        }

        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="experiment"></param>
        public void DeleteExperiment(Experiment experiment)
        {
            int id = experiment.Id;
            DBManager experimentDBManager = DBManager.dbManagerDic[DBManager.ENTITY_EXPERIMENT];

            experimentDBManager.Delete(id);

            string attachInfo = getAttachInfoDBManager(experiment);
            if (attachInfo != null)
            {
                DBManager.dbManagerDic[attachInfo].DeleteByCondtion("experimentCode='" + experiment.Code + "'");
            }

            string record = getRecordDBManager(experiment);
            if (record != null)
            {
                DBManager.dbManagerDic[record].DeleteByCondtion("experimentCode='" + experiment.Code + "'");
            }
  
        }


        /// <summary>
        /// 保存对象
        /// </summary>
        /// <param name="experiment"></param>
        public void SaveExperiment(Experiment experiment)
        {
            DBManager experimentDBManager = DBManager.dbManagerDic[DBManager.ENTITY_EXPERIMENT];
            experimentDBManager.Insert(experiment);

            string attachInfo = getAttachInfoDBManager(experiment);
            if (attachInfo != null)
            {
                DBManager.dbManagerDic[attachInfo].Insert(experiment);
            }

        }


        /// <summary>
        /// 保存试验结果路径
        /// </summary>
        /// <param name="experiment"></param>
        public void SaveExperimentFilePath(Experiment experiment)
        {
            experiment.FilePath = experiment.DefaultSavePath;
            DBManager experimentDBManager = DBManager.dbManagerDic[DBManager.ENTITY_EXPERIMENT];
            experimentDBManager.Update(experiment.Id, experiment);
            //this.ExperimentDBManager.UpdateFilePath(experiment.Code, experiment.DefaultSavePath);

        }

        /// <summary>
        /// 生成试验编号
        /// </summary>
        /// <returns></returns>
        public static string GenerateExperimentCode(ExperimentType experimentType, PumpType pumpType)
        {
            String code = experimentType.ToString() + "-" + pumpType.ToString() + "-" + string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now);
            return code;
        }

        /// <summary>
        /// 结束试验
        /// </summary>
        /// <param name="experiment"></param>
        public void FinishExperiment(Experiment experiment)
        {
            ExperimentExcelManager.SaveExperiment(experiment);
            //先保存图片，再保存
            this.SaveExperimentFilePath(experiment);

            this.SaveExperiment(experiment);


        }

        /*
        /// <summary>
        /// 根据条件查询（查询相关函数后续需要分开）
        /// </summary>
        /// <param name="query">查询条件对象</param>
        /// <returns>查询结果</returns>
        public DataTable QueryExperiment(BaseQuery query)
        {
            return ExperimentDBManager.GetDataList(query);
        }

        /// <summary>
        /// 获取符合条件的记录数量
        /// </summary>
        /// <param name="query">查询条件对象</param>
        /// <returns>查询结果</returns>
        public int GetCount(BaseQuery query)
        {
            return ExperimentDBManager.GetCount(query);
        }


        /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="experiment"></param>
        public void DeleteExperiment(Experiment experiment)
        {
            int id = experiment.Id;
            this.ExperimentDBManager.Delete(id);
            this.ExperimentAttachInfoDBManager.DeleteByCondtion("experimentCode='"+experiment.Code+"'");
            this.ExperimentRecordDBManager.DeleteByCondtion("experimentCode='" + experiment.Code+"'");
        }

        /// <summary>
        /// 保存对象
        /// </summary>
        /// <param name="experiment"></param>
        public void SaveExperiment(Experiment experiment)
        {
            //CentrifugalPumpPerfExperiment perfExperiment = (CentrifugalPumpPerfExperiment)experiment;
            ExperimentDBManager.Insert(experiment);
            ExperimentAttachInfoDBManager.Insert(experiment);
        }

        /// <summary>
        /// 保存试验结果路径
        /// </summary>
        /// <param name="experiment"></param>
        public void SaveExperimentFilePath(Experiment experiment)
        {
            experiment.FilePath = experiment.DefaultSavePath;
            this.ExperimentDBManager.Update(experiment.Id, experiment);
            //this.ExperimentDBManager.UpdateFilePath(experiment.Code, experiment.DefaultSavePath);
            
        }

        /// <summary>
        /// 生成试验编号
        /// </summary>
        /// <returns></returns>
        public static string GenerateExperimentCode(ExperimentType experimentType, PumpType pumpType)
        {
            String code = experimentType.ToString() + "-"+ pumpType.ToString()+ "-" + string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now);
            return code;
        }*/







        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public virtual Experiment GetExperimentInfo()
        {
            return null;
        }


        /// <summary>
        /// 根据id批量删除记录
        /// </summary>
        /// <param name="id"></param>
        public void RemoveExperimentRecordByIds(int[] id)
        {
            if (id == null || id.Length == 0)
            {
                return;
            }

            StringBuilder condition = new StringBuilder();
            condition.Append(" Id in (");
            for (int i = 0; i < id.Length - 1; i++)
            {
                condition.Append(id[i].ToString() + ",");
            }
            condition.Append(id[id.Length - 1].ToString() + ")");
            

            DBManager.dbManagerDic[recordType].DeleteByCondtion(condition.ToString());

        }

        /// <summary>
        /// 生成试验记录
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        public int SaveExperimentRecord(String recordType, ExperimentRecord record)
        {
            return DBManager.dbManagerDic[recordType].Insert(record);
        }

        public void FetchData()
        {
            this.envDataManager.FetchData();
        }

        #endregion

    }
}
